package it.robertobifulco.ias.test;

import static org.junit.Assert.fail;
import it.robertobifulco.ias.IAS;
import it.robertobifulco.ias.MaximumNumberofOccurenceExceededException;
import it.robertobifulco.ias.Operation;
import it.robertobifulco.ias.UnauthorizedOperationException;
import it.robertobifulco.ias.principalmanager.ImpossibleToIdentifyPrincipalException;
import it.robertobifulco.ias.principalmanager.Principal;
import it.robertobifulco.ias.rolemanager.Role;
import it.robertobifulco.ias.rolemanager.RoleUndefinedException;
import it.robertobifulco.ias.test.operations.Write;
import it.robertobifulco.ias.test.repository.OperationRepositoryTEST;
import it.robertobifulco.ias.test.repository.PrincipalRepositoryTEST;
import it.robertobifulco.ias.test.repository.RoleRepositoryTEST;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class IAS_TEST {

	private IAS ias;

	@Before
	public void initialize() {
		try {
			ias = IAS.createIAS(new PrincipalRepositoryTEST(),
					new RoleRepositoryTEST(), false,
					new OperationRepositoryTEST());
			
			Operation op = new Write();
			
			ias.getOperations().addOperation(op);
		} catch (MaximumNumberofOccurenceExceededException e) {
			fail("impossible to create IAS first instance");
		}
	}

	@After
	public void close() {

		if (ias != null) {
			ias.dispose();
		}
	}

	@Test
	public void testIAS() {
		try {
			ias = IAS.createIAS(new PrincipalRepositoryTEST(),
					new RoleRepositoryTEST(), false,
					new OperationRepositoryTEST());

		} catch (MaximumNumberofOccurenceExceededException e) {
			fail("Impossible to perform IAS creation");
		}
	}

	@Test
	public void testGetPrincipal() {
		// id e psw corretti
		try {
			ias.getPrincipal("roberto", "admin");
		} catch (ImpossibleToIdentifyPrincipalException e) {
			fail("Utente non autenticato: " + e.getMessage());
		}
		// id inesistente
		try {
			Principal p = ias.getPrincipal("robertone", "admin");
			fail("Utente inesistente autenticato come: " + p.getId());
		} catch (ImpossibleToIdentifyPrincipalException e) {

		}
		// pw scorretta
		try {
			Principal p = ias.getPrincipal("roberto", "adminnnnn");
			fail("Utente autenticato con psw scorretta!!: " + p.getId());
		} catch (ImpossibleToIdentifyPrincipalException e) {

		}
	}

	@Test
	public void testGetRole() {
		// Ruolo corretto
		try {
			Role role = ias.getRole("Admin");
			if (!role.getName().equals("Admin"))
				fail("Restituito ruolo sbagliato!");
		} catch (RoleUndefinedException e) {
			fail("Ruolo non riconosciuto!");
		}
		// Ruolo errato
		try {
			ias.getRole("Admino");
			fail("Ruolo riconosciuto, anche se era errato!");
		} catch (RoleUndefinedException e) {

		}

	}

	@Test
	public void testGetOperation() {

		Principal roberto;
		try {
			roberto = ias.getPrincipal("roberto", "admin");
			Principal rob = ias.getPrincipal("rob", "user");

//			Operatione consentita al principal
			try {
				ias.getOperation("write", roberto);
			} catch (UnauthorizedOperationException e) {
				fail("Operazione consentita negata!");
			} catch (RoleUndefinedException e) {
				fail("Errore nel ruolo assegnato al Principal!!");
			} 
//			Operatione inesistente
			try {
				Operation op = ias.getOperation("writer", roberto);
				fail("E' stata restituita un'operazione con id inesistente!!: " + op.getID());
			} catch (UnauthorizedOperationException e) {
				
			} catch (RoleUndefinedException e) {
				fail("Errore nel ruolo assegnato al Principal!!");
			}
//			Operatione non consentita per il principal
			try {
				ias.getOperation("write", rob);
				fail("E' stata restituita un'operazione inibita al Principal!");
			} catch (UnauthorizedOperationException e) {

			} catch (RoleUndefinedException e) {
				fail("Errore nel ruolo assegnato al Principal!!");
			}
		} catch (ImpossibleToIdentifyPrincipalException e1) {
			fail("Errore nel recupero dei Principal!!");
		}
	}
	
	@Test
	public void testGetOperationExtraInfos() {
		Principal roberto;
		ias.addPermissionHandler(new PermissionHandlerTEST());
		String infos = "roberto";
		
		try {
			roberto = ias.getPrincipal("roberto", "admin");
			Principal rob = ias.getPrincipal("rob", "user");
			
//			Operatione consentita al principal
			try {
				ias.getOperation("write", roberto, infos);
			} catch (UnauthorizedOperationException e) {
				fail("Operazione consentita negata!");
			} catch (RoleUndefinedException e) {
				fail("Errore nel ruolo assegnato al Principal!!");
			} 
//			Operatione inesistente
			try {
				Operation op = ias.getOperation("writer", roberto, infos);
				fail("E' stata restituita un'operazione con id inesistente!!: " + op.getID());
			} catch (UnauthorizedOperationException e) {
				
			} catch (RoleUndefinedException e) {
				fail("Errore nel ruolo assegnato al Principal!!");
			}
//			Operatione non consentita per il principal
			try {
				ias.getOperation("read", rob, infos);
				fail("E' stata restituita un'operazione inibita al Principal!");
			} catch (UnauthorizedOperationException e) {

			} catch (RoleUndefinedException e) {
				fail("Errore nel ruolo assegnato al Principal!!");
			}
			
		} catch (ImpossibleToIdentifyPrincipalException e) {
			fail("Errore nel recupero dei Principal!!");
		}
		
	}

}
